Jak na zpravu WM_DRAWITEM - zmena barvy menu
Otázka od: Ing. Jiri SOKOL
25. 11. 2002 14:14
Ahoj,
chtel jsem si zmenit barvu MainMenu. V helphu a tak ruzne jsem se docetl, ze je
mozne tohoto
docilit, kdyz menu nastavim vlastnost OwnerDraw na true a odchytim si zpravu
WM_DRAWITEM.
OK, to jsem zvladl. Problem mam, ze lparametr teto zpravy je pointer na
pole(record) typu
DRAWITEMSTRUCT, ktere obsahuje "item-drawing information".
Jenze neumim ten parametr spravne pouzit. Delam toto:
procedure TForm1.WndProc(var msg:TMessage);
var
Stru:TDrawItemStruct;
begin
if (msg.message=WM_DRAWITEM)and(msg.wParam=0) then
begin
stru:=@msg.lparam;
ShowMessage('Handle menu by mel byt: '+IntToStr(stru.hwndItem));
end;
end;
Problem je v tom, ze se nedostavam ke spravnym datum. Nekde delam chybu, ale
netusim kde. Ten
pointer pouzivam nejspis spatne, ale jak je to spravne?
Poradite? Diky.
Jirka
Ing. Jiri Sokol, js-delphi@seznam.cz, +420251431187
D6ProfSP2,WinNT
amatersky programator
______________________________________________________________________
Reklama:
Poctenicko pro kazdy den: http://www.novinky.cz
Odpovedá: Ondrej Kelle
25. 11. 2002 15:41
> chtel jsem si zmenit barvu MainMenu. V helphu a tak ruzne
> jsem se docetl, ze je mozne tohoto
> docilit, kdyz menu nastavim vlastnost OwnerDraw na true a
> odchytim si zpravu WM_DRAWITEM.
V Delphi 6 nemusis tu spravu odchytavat, staci, ak si nastavis
TMainMenu.OwnerDraw na True (alebo priradis Images) a potom mozes pouzit
event OnDrawItem alebo OnAdvancedDrawItem. Musis ale ten event priradit
kazdej polozke zvlast.
Ak to chces priradit v runtime vsetkym polozkam v menu, da sa to napriklad
takto:
type
TMenuItemProc = procedure (Item: TMenuItem) of object;
procedure TForm1.UpdateItem(Item: TMenuItem);
begin
Item.OnDrawItem := MainMenu1DrawItem;
end;
procedure IterateMenuItems(Items: TMenuItem; IterateProc: TMenuItemProc);
var
I: Integer;
begin
for I := 0 to Items.Count - 1 do
IterateMenuItems(Items[I], IterateProc);
IterateProc(Items);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MainMenu1.OwnerDraw := True;
IterateMenuItems(MainMenu1.Items, UpdateItem);
end;
procedure TForm1.MainMenu1DrawItem(Sender: TObject; ACanvas: TCanvas; ARect:
TRect; Selected: Boolean);
begin
// a tu si uz kreslis sam
end;
HTH
TOndrej
Odpovedá: Jaroslav Buček
25. 11. 2002 17:02
----- Original Message -----
From: "Ing. Jiri SOKOL" <JS-delphi@seznam.cz>
OK, to jsem zvladl. Problem mam, ze lparametr teto zpravy je pointer na
pole(record) typu
DRAWITEMSTRUCT, ktere obsahuje "item-drawing information".
Jenze neumim ten parametr spravne pouzit. Delam toto:
-----------------------------
pCaption : PChar;
DI : PDrawItemStruct;
DI := Ptr(msg.lparam);
// DI.itemState = 1 kdyz je kurzor nad item - 257 je na Win2000
// DI.itemState = 0 kdyz je kurzor mimo item
// DI.itemAction = 1 kdyz polozka nebyla zobrazena a musi se vykreslit
// DI.itemAction = 2 kdyz polozka byla zobrazena a nemusi se prekreslit
pCaption := Ptr(DI.itemData); // vrati caption
TextOut(DI.hDC, DI.rcItem.Left, DI.rcItem.Top, pCaption,
StrLen(pCaption));
Jsou to jen kousky z jednoho meho programu. Snad Ti to pomuze. Ty konstanty
jsem zjistoval nejak zbesile, takze ani nevim, jak se jmenuji spravne
konstanty.
Ahoj, Jarda
Odpovedá: Petr Vones
25. 11. 2002 16:55
From: "Jaroslav Buček" <bucek@eskon.cz>
> // DI.itemState = 1 kdyz je kurzor nad item - 257 je na Win2000
> // DI.itemState = 0 kdyz je kurzor mimo item
> // DI.itemAction = 1 kdyz polozka nebyla zobrazena a musi se vykreslit
> // DI.itemAction = 2 kdyz polozka byla zobrazena a nemusi se prekreslit
Tak takhle opravdu ne. Co se treba podivat do dokumentace a pouzit konstanty ?
ms-help://MS.PSDK.1033/shellcc/platform/commctls/comboboxes/comboboxreference/
comboboxstructures/drawitemstruct.htm
> Jsou to jen kousky z jednoho meho programu. Snad Ti to pomuze. Ty konstanty
> jsem zjistoval nejak zbesile, takze ani nevim, jak se jmenuji spravne
> konstanty.
Mozna by bylo dobre to delat zpusobem jakym to nabizi VCL, viz odpoved kterou
poslal Ondrej Kelle.
Petr Vones